package wicket;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PropertyListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.PropertyModel;
import org.uqbar.commons.model.UserException;

import plantasVsZombies.Tablero;
import plantaszombies.Planta;
import plantaszombies.Semilla;
import plantaszombies.Terreno;
import plantaszombies.Zombie;

public class TableroPage extends WebPage {

	private static final long serialVersionUID = 1L;

	private Tablero tablero;

	public TableroPage(Tablero tablero) {
		this.tablero = tablero;
		this.addJardin();

		this.addActionPanel();

		this.addLogForm();
		this.addAtacarForm();
		this.addPlantarForm();

		this.tablero.jugar();
	}

	protected void addActionPanel() {
		Form<Tablero> actionForm = new Form<Tablero>("actionForm",
				new CompoundPropertyModel(this.tablero));
		actionForm.add(new Label("recursos"));
		this.add(actionForm);
		this.addActions(actionForm);
	}

	protected void addJardin() {
		WebMarkupContainer panel = new WebMarkupContainer("jardinForm",
				new CompoundPropertyModel(this.tablero));
		this.add(panel);
		createTerrenoListView(panel, "terrenosTerrestres");
		createTerrenoListView(panel, "terrenosAcuaticos");
	}

	protected void createTerrenoListView(WebMarkupContainer panel,
			String propertyName) {
		panel.add(new PropertyListView<Terreno>(propertyName) {
			protected void populateItem(final ListItem<Terreno> item) {
				addTerrenoClassBehavior(item);
				item.add(new PropertyListView<Planta>("plantas") {
					protected void populateItem(
							final ListItem<Planta> itemPlanta) {
						itemPlanta.add(new Label("toString"));
					}
				});
			}
		});
	}

	protected void addTerrenoClassBehavior(final ListItem<Terreno> item) {
		item.add(new AttributeModifier("class",
				new AbstractReadOnlyModel<String>() {
					@Override
					public String getObject() {
						return item.getModelObject().getTipoTerrenoToString();
					}
				}));
	}

	protected void addLogForm() {
		Form<Tablero> logsForm = new Form<Tablero>("logsForm",
				new CompoundPropertyModel(this.tablero));
		this.generarListaDeLogs(logsForm);
		this.add(logsForm);
	}

	protected void addAtacarForm() {
		Form<Tablero> elegirZombieForm = new Form<Tablero>("elegirZombieForm", new CompoundPropertyModel(this.tablero));
		this.generarOpcionesZombieForm(elegirZombieForm);
		this.addButtons(elegirZombieForm);
		this.add(elegirZombieForm);
	}

	protected void addPlantarForm() {
		Form<Tablero> plantarForm = new Form<Tablero>("plantarForm", new CompoundPropertyModel(this.tablero));
		this.generarOpcionesPlantarForm(plantarForm);
		plantarForm.add(new TextField<String>("fila"));
		plantarForm.add(new TextField<String>("columna"));
		this.add(plantarForm);
		this.addButtonPlantar(plantarForm);

	}

	private void generarListaDeLogs(Form<Tablero> logsForm) {
		logsForm.add(new PropertyListView<Zombie>("logs") {
			@Override
			protected void populateItem(final ListItem<Zombie> item) {
				item.add(new Label("toString"));
			}
		});
	}

	private void generarOpcionesPlantarForm(Form<Tablero> plantarForm) {
		plantarForm.add(new DropDownChoice<Semilla>(
				//
				"semillas", //
				propertyModel(plantarForm, "semilla"), //
				propertyModel(plantarForm, "semillas"),
				new ChoiceRenderer<Semilla>() {
					@Override
					public Object getDisplayValue(Semilla semilla) {
						return semilla.getNombre();
					}
				}));

	}

	private void generarOpcionesZombieForm(Form<Tablero> elegirZombieForm) {
		elegirZombieForm.add(new DropDownChoice<Zombie>(
				//
				"zombies", //
				propertyModel(elegirZombieForm, "zombieAtacante"), //
				propertyModel(elegirZombieForm, "almanaque"),
				new ChoiceRenderer<Zombie>() {
					@Override
					public Object getDisplayValue(Zombie object) {
						return object.getNombre();
					}
				}));
		elegirZombieForm.add(new TextField<String>("filaAAtacar"));
		elegirZombieForm.add(new FeedbackPanel("feedbackPanel"));
	}

	private void addButtons(Form<Tablero> elegirForm) {
		elegirForm.add(new Button("atacar") {
			@Override
			public void onSubmit() {
				try {
					TableroPage.this.tablero.atacarWicket();
				} catch (UserException e) {
					error(e.getMessage());
				}
			}
		});

	}

	private void addButtonPlantar(Form<Tablero> plantarForm) {
		plantarForm.add(new Button("plantar") {
			@Override
			public void onSubmit() {
				try {
					TableroPage.this.tablero.plantarWicket();
				} catch (UserException e) {
					error(e.getMessage());
				}
			}
		});

	}

	private void addActions(Form<Tablero> actionForm) {
		actionForm.add(new Button("reiniciar") {
			@Override
			public void onSubmit() {
				TableroPage.this.tablero.reiniciar();
			}

		});

		actionForm.add(new Button("irAlJardinZen") {
			@Override
			public void onSubmit() {
				this.setResponsePage(new JardinZenPage(TableroPage.this, TableroPage.this.tablero.getPartida()));
			}
		});

		actionForm.add(new Button("almanaque") {
			@Override
			public void onSubmit() {
				this.setResponsePage(new AlmanaquePage(TableroPage.this));
			}
		});
	}

	protected PropertyModel propertyModel(Form<Tablero> elegirForm,	String propertyName) {
		return new PropertyModel<Zombie>(elegirForm.getDefaultModelObject(), propertyName);
	};

}
